package com.hanqian.kepler.web.controller.core;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.hanqian.kepler.common.bean.jqgrid.JqGridContent;
import com.hanqian.kepler.common.bean.jqgrid.JqGridFilter;
import com.hanqian.kepler.common.bean.jqgrid.JqGridPager;
import com.hanqian.kepler.common.bean.jqgrid.JqGridReturn;
import com.hanqian.kepler.common.bean.result.AjaxResult;
import com.hanqian.kepler.common.enums.BaseEnumManager;
import com.hanqian.kepler.common.enums.DictEnum;
import com.hanqian.kepler.common.jpa.specification.Rule;
import com.hanqian.kepler.common.jpa.specification.SpecificationFactory;
import com.hanqian.kepler.core.entity.primary.core.Target;
import com.hanqian.kepler.core.entity.primary.core.TargetEvaluate;
import com.hanqian.kepler.core.entity.primary.core.TargetEvaluateDetail;
import com.hanqian.kepler.core.entity.primary.sys.Dict;
import com.hanqian.kepler.core.service.core.TargetEvaluateDetailService;
import com.hanqian.kepler.core.service.core.TargetEvaluateService;
import com.hanqian.kepler.core.service.core.TargetService;
import com.hanqian.kepler.core.vo.TargetEvaluateVo;
import com.hanqian.kepler.flow.entity.User;
import com.hanqian.kepler.flow.enums.FlowEnum;
import com.hanqian.kepler.flow.vo.ProcessLogVo;
import com.hanqian.kepler.security.annotation.CurrentUser;
import com.hanqian.kepler.web.annotation.RequestJsonParam;
import com.hanqian.kepler.web.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 指标评测
 * ======================================
 * @author dzw
 * @date 2021/1/26 16:16
 * =======================================
 */
@Controller
@RequestMapping("targetEvaluate")
public class TargetEvaluateController extends BaseController {

    @Autowired
    private TargetService targetService;
    @Autowired
    private TargetEvaluateService targetEvaluateService;
    @Autowired
    private TargetEvaluateDetailService targetEvaluateDetailService;

    /**
     * list
     */
    @GetMapping("list")
    @ResponseBody
    public JqGridReturn list(@CurrentUser User user, JqGridPager pager, @RequestJsonParam("filters") JqGridFilter filters,
                             String targetId){
        Pageable pageable = getJqGridPageable(pager);
        List<Rule> rules = getJqGridSearchWithFlow(filters);
        if(StrUtil.isNotBlank(targetId)) rules.add(Rule.eq("target.id", targetId));
        JqGridContent<TargetEvaluate> jqGridContent = targetEvaluateService.getJqGridContentWithFlow(rules, pageable, user);

        List<Map<String, Object>> dataRows = new ArrayList<>();
        jqGridContent.getList().forEach(entity -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", entity.getId());
            map.put("target.name", entity.getTarget()!=null ? entity.getTarget().getName() : "");
            map.put("creator.name", entity.getCreator()!=null ? entity.getCreator().getName() : "");
            map.put("createTime", DateUtil.format(entity.getCreateTime(), "yyyy-MM-dd HH:mm"));

            dataRows.add(map);
        });
        return getJqGridReturn(dataRows, jqGridContent.getPage());
    }

    /**
     * 判断是否已经评测过了
     */
    @RequestMapping("check")
    @ResponseBody
    public AjaxResult check(@CurrentUser User user, String targetId){
        return targetEvaluateService.checkHas(user.getId(), targetId) ? AjaxResult.error("您已经测评过了") : AjaxResult.success();
    }

    /**
     * read页面
     */
    @GetMapping("read")
    public String read(String keyId, Model model){
        TargetEvaluate targetEvaluate = targetEvaluateService.get(keyId);
        List<Dict> typeList = getDictList(DictEnum.target_evaluate_type);
        model.addAttribute("targetEvaluate", targetEvaluateService.vo(targetEvaluate, typeList));
        return "main/core/targetEvaluate_read";
    }

    /**
     * input页面
     */
    @GetMapping("input")
    public String input(String keyId, Model model, String parentId){
        TargetEvaluate targetEvaluate = targetEvaluateService.get(keyId);
        List<Dict> typeList = getDictList(DictEnum.target_evaluate_type);
        model.addAttribute("targetEvaluate", targetEvaluateService.vo(targetEvaluate, typeList));
        model.addAttribute("target", targetService.get(parentId));
        return "main/core/targetEvaluate_input";
    }

    private TargetEvaluate setDataTargetEvaluate(User user, String keyId, String targetId){
        TargetEvaluate targetEvaluate = targetEvaluateService.get(keyId);
        if(targetEvaluate == null){
            targetEvaluate = new TargetEvaluate();
            targetEvaluate.setCreator(user);
        }
        targetEvaluate.setTarget(targetService.get(targetId));
        return targetEvaluate;
    }

    /**
     * 保存
     */
    @PostMapping("save")
    @ResponseBody
    public AjaxResult save(@CurrentUser User user, String keyId, String targetId, String detailJson){
        TargetEvaluate targetEvaluate = setDataTargetEvaluate(user,keyId,targetId);
        if(targetEvaluate.getTarget() == null) return AjaxResult.error("未获取到主指标信息");
        if(!JSONUtil.isJsonArray(detailJson)) return AjaxResult.error("评测数据异常");

        if(StrUtil.isBlank(targetEvaluate.getId())){
            AjaxResult ajaxResult =  targetEvaluateService.draft(targetEvaluate);
            targetEvaluate = targetEvaluateService.get(ajaxResult.getId());
        }else{
            targetEvaluate = targetEvaluateService.save(targetEvaluate);
        }

        return saveDetail(targetEvaluate, detailJson);
    }

    /**
     * 提交
     */
    @PostMapping("commit")
    @ResponseBody
    public AjaxResult commit(@CurrentUser User user, ProcessLogVo processLogVo, String targetId, String detailJson){
        TargetEvaluate targetEvaluate = setDataTargetEvaluate(user,processLogVo.getKeyId(),targetId);
        if(targetEvaluate.getTarget() == null) return AjaxResult.error("未获取到主指标信息");
        if(!JSONUtil.isJsonArray(detailJson)) return AjaxResult.error("评测数据异常");
        if(targetEvaluateService.checkHas(user.getId(), targetId)) return AjaxResult.error("您已经执行过评测了");

        AjaxResult ajaxResult =  targetEvaluateService.commit(targetEvaluate, processLogVo);
        if(1 == ajaxResult.getState()){
            targetEvaluate = targetEvaluateService.get(ajaxResult.getId());
        }
        return saveDetail(targetEvaluate, detailJson);
    }

    //主表保存后开始保存评测详情
    private AjaxResult saveDetail(TargetEvaluate targetEvaluate, String detailJson){
        if(targetEvaluate == null) return AjaxResult.error("主表保存失败");
        JSONArray jsonArray = JSONUtil.parseArray(detailJson);
        for(int i=0;i<jsonArray.size();i++){
            TargetEvaluateVo.Detail detailVo = JSONUtil.toBean(jsonArray.getJSONObject(i), TargetEvaluateVo.Detail.class);
            TargetEvaluateDetail detail = targetEvaluateDetailService.get(detailVo.getId());
            if(detail == null) detail = new TargetEvaluateDetail();
            detail.setTargetEvaluateTypeDict(dictService.get(detailVo.getDictId()));
            detail.setTargetEvaluate(targetEvaluate);
            detail.setScore(detailVo.getScore());
            targetEvaluateDetailService.save(detail);
        }
        return AjaxResult.success("保存成功");
    }

    /**
     * 根据指标id获取此指标的所有评测（雷达图）
     */
    @RequestMapping("radarList")
    @ResponseBody
    public AjaxResult radarList(String targetId){
        if(StrUtil.isBlank(targetId)) return AjaxResult.error("未获取到指标id");

        List<Dict> typeList = getDictList(DictEnum.target_evaluate_type);
        List<Rule> rules = new ArrayList<>();
        rules.add(Rule.eq("state", BaseEnumManager.StateEnum.Enable));
        rules.add(Rule.ne("processState", FlowEnum.ProcessState.Draft));
        rules.add(Rule.eq("target.id", targetId));
        List<TargetEvaluate> targetEvaluates = targetEvaluateService.findAll(SpecificationFactory.where(rules));
        List<Map<String, Object>> valueDataList = new ArrayList<>();
        targetEvaluates.forEach(t -> {
            TargetEvaluateVo vo = targetEvaluateService.vo(t, typeList);
            Map<String, Object> data = new LinkedHashMap<>();
            data.put("id", vo.getId());
            data.put("creatorName", vo.getCreatorName());
            data.put("valueList", vo.getDetailList().stream().map(TargetEvaluateVo.Detail::getScore).collect(Collectors.toList()));

            valueDataList.add(data);
        });
        return AjaxResult.success("获取成功", valueDataList);
    }

}
